from datetime import datetime, timedelta
import re


def generate_dates_by_rules(rules_string):
    """
    根据规则字符串生成日期，所有结果汇总到一个去重并排序的列表中

    参数:
        rules_string: 规则字符串，用分号分隔多个规则（如"[1年][1月];[2年][2月][-3天,1天]"）

    返回:
        list: 所有生成日期的汇总列表（去重、按时间排序）
    """
    # 使用当前系统日期作为基准
    base_date = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)# 获取当前系统日期
# 判断规则中包含天级标签
    def has_day_tag(rule):# 判断规则中是否包含天级标签
        """判断规则中是否包含天级标签"""
        return re.search(r'\[(-?\d+天(?:,\s*-?\d+天)*)\]', rule) is not None# 判断规则中是否包含天级标签
# 解析多值
    def parse_multi_values(rule, unit):# 解析多值
        """解析规则中指定单位的多值"""
        pattern = re.compile(rf'\[((?:-?\d+{unit}(?:,\s*-?\d+{unit})*))\]')# 创建正则表达式模式
        match = pattern.search(rule)# 匹配规则中的多值
        if not match:# 如果没有匹配到多值，则返回空列表
            return []
        values_str = match.group(1)# 获取匹配到的多值字符串
        return [int(v.strip().replace(unit, '')) for v in values_str.split(',')]# 解析多值字符串为整数列表
# 计算偏移后的基准日期
    def calculate_offset_base(base_date, rule):# 计算偏移后的基准日期
        """计算偏移后的基准日期"""
        current = base_date# 初始化当前日期

        # 处理年份偏移
        year_values = parse_multi_values(rule, '年')# 解析多值字符串为整数列表
        if year_values:# 如果有年份偏移，则计算偏移后的基准日期
            year_offset = year_values[0] - 1
            try:
                current = current.replace(year=current.year + year_offset)
            except ValueError:
                current = datetime(current.year + year_offset, 3, 1)

        # 处理月份偏移
        month_values = parse_multi_values(rule, '月')# 解析多值字符串为整数列表
        if month_values:# 如果有月份偏移，则计算偏移后的基准日期
            month_offset = month_values[0] - 1# 计算月份偏移
            new_month = current.month + month_offset# 计算新的月份
            new_year = current.year + (new_month - 1) // 12# 计算新的年份
            new_month = (new_month - 1) % 12 + 1# 计算新的月份
            try:
                current = current.replace(year=new_year, month=new_month)# 计算偏移后的日期
            except ValueError:
                last_day = (datetime(new_year, new_month + 1, 1) - timedelta(days=1)).day# 计算最后一天
                current = current.replace(year=new_year, month=new_month, day=last_day)# 计算偏移后的日期

        return current# 返回计算后的基准日期
# 生成从基准日开始到下个月的日期
    def generate_month_period_dates(base_date):# 生成从基准日开始到下个月的日期
        """生成从基准日开始到下个月同日的日期"""
        start_date = base_date
        try:
            end_date = start_date.replace(month=start_date.month + 1)
        except ValueError:
            end_date = start_date.replace(year=start_date.year + 1, month=1)

        dates = []
        current_date = start_date
        while current_date <= end_date:
            dates.append(current_date.strftime('%Y/%m/%d'))
            current_date += timedelta(days=1)
        return dates
# 生成单个规则对应的日期
    def generate_rule_dates(rule, base_date):
        """生成单个规则对应的日期"""
        offset_base = calculate_offset_base(base_date, rule)

        if has_day_tag(rule):
            day_values = parse_multi_values(rule, '天')
            return [(offset_base + timedelta(days=day_val - 1)).strftime('%Y/%m/%d')
                    for day_val in day_values]
        else:
            return generate_month_period_dates(offset_base)

    # 处理所有规则并汇总日期
    rules = [rule.strip() for rule in rules_string.split(';') if rule.strip()]
    all_dates = []

    for rule in rules:
        all_dates.extend(generate_rule_dates(rule, base_date))

    # 去重并按时间排序
    return sorted(list(set(all_dates)))# 返回去重并排序的日期列表


# 示例调用
if __name__ == "__main__":
    # 测试规则
    test_rules = "[1天]"

    # 生成并获取汇总日期列表
    all_dates = generate_dates_by_rules(test_rules)
    print(all_dates)
    # 打印结果

